今天來到 Public Action 第二章節介紹
間隔監控並且返回事件 logs
一樣以程式說明
import { http, createPublicClient, stringify } from 'viem';
import { mainnet } from 'viem/chains';
const client = createPublicClient({
chain: mainnet,
transport: http(),
});
// TODO: convert to `parseAbiItem`.
const event = {
inputs: [
{
indexed: true,
name: 'from',
type: 'address',
},
{
indexed: true,
name: 'to',
type: 'address',
},
{
indexed: false,
name: 'value',
type: 'uint256',
},
],
name: 'Transfer',
type: 'event',
};
client.watchEvent({
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
event,
// poll:false // 是否為 webstocket
// args: {
// from:0xd8da6bf26964af9d7eed9e03e53415d37aa96045
// to:
// }
// pollingInterval: 1_000, // 每 1 秒觀察一次,如果沒有設定看 RpcServer 自己預設是多少
onLogs: (logs) => {
console.log(logs[0].blockNumber);
console.log(stringify(logs, null, 2));
},
});
這裡的範例是監控 USDT 的 Transfer
的事件。要使用args
只有在屬性有設定 indexed
才可以使控制喔!!
有一個誤區要先記得 pollingInterval
不管你有沒有設定他的觸發就是每隔多久找一次,而不是發生 event 它就呈現…
另外還有 poll
這屬性是判定是否為 webstocket 有什麼不同呢?
如果是 true
其實他就會通過 eth_subscribe
去訂閱,用這樣的方法就會是觸發 event 就會回覆。
程式實作:
https://github.com/0xRory/ITHepleViem/blob/main/examples/3_5_publicAction_WatchEvent.js
驗證所提供的地址是否簽署
此操作支持驗證由智慧合約帳戶或外部擁有的帳戶簽名的消息。該 verifyMessage
實用程式僅支援外部擁有的帳戶。隨著越來越多的錢包實現帳戶抽象,這一點變得越來越重要。
這段我用程式說明作法
import { createPublicClient, http, createWalletClient, custom } from 'viem';
import { mainnet } from 'viem/chains';
const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
}); // 建立 Client
const walletClient = createWalletClient({
transport: custom(window.ethereum)
})
// JSON-RPC Account
const [account] = await walletClient.getAddresses() //從建立錢包中給帳號
// Local Account
const account = privateKeyToAccount(...) // 或是你使用本地建立錢包...(請注意這裡是私鑰)
// 建立 sign 請記得如果要使用這個話一定要連接錢包並使用(私鑰)
const signature = await walletClient.signMessage({
account,
message: 'hello world',
})
// 這裡給一個簡單的範例示意
const valid = await publicClient.verifyMessage({
address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
message: 'hello world',
signature:
'0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c',
});
console.log('valid', valid);
就如前面所說這樣的,這個簽章是使用你的私鑰所建立的那代表如果你有signature 和 Address 你就可以確認這是你專屬的,這樣使用的話對於是不是你這件事情就比較好判定了。
此操作支持驗證由智慧合約帳戶或外部擁有帳戶(通過ERC-6492)簽名的類型數據。該 verifyTypedData
實用程式僅支援外部擁有的帳戶。隨著越來越多的錢包實現帳戶抽象,這一點變得越來越重要。
先看一下程式碼:
import { createPublicClient, http, createWalletClient, custom } from 'viem';
import { mainnet } from 'viem/chains';
const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
}); // 建立 Client
const walletClient = createWalletClient({
transport: custom(window.ethereum)
})
// JSON-RPC Account
const [account] = await walletClient.getAddresses() //從建立錢包中給帳號
// Local Account
const account = privateKeyToAccount(...) // 或是你使用本地建立錢包...(請注意這裡是私鑰)
// 類別
const domain = {
name: 'Ether Mail',
version: '1',
chainId: 1,
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
}
// The named list of all type definitions
const types = {
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' },
],
Mail: [
{ name: 'from', type: 'Person' },
{ name: 'to', type: 'Person' },
{ name: 'contents', type: 'string' },
],
}
// 訊息從 cow -> Bob 來的訊息 Hello, Bob!
const message = {
from: {
name: 'Cow',
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
},
to: {
name: 'Bob',
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
},
contents: 'Hello, Bob!',
}
const signature = await walletClient.signTypedData({
account,
domain,
types,
primaryType: 'Mail',
message,
})
// 驗證定義類型資料
const valid = await publicClient.verifyTypedData({
address: account.address,
domain,
types,
primaryType: 'Mail',
message,
signature,
})
這比較難我試著說明看看,簡單來說就是一般的驗證都是單一的,沒有什麼類別,但是如果有了domain 代表驗證是會有類別,有設定的合約。這樣就可以有很多應用了,你可以鏈上驗證+線下驗證做你要的機制。
程式實作:
https://github.com/0xRory/ITHepleViem/blob/main/examples/3_6_verifyMessage.js
參考:
https://viem.sh/docs/actions/public/watchEvent.html
https://viem.sh/docs/actions/public/verifyMessage.html
https://viem.sh/docs/actions/public/verifyTypedData.html